//
//  BGCommonConst.h
//  BluetoothCameraHead
//
//  Created by KBTC－iMac on 16/11/21.
//  Copyright © 2016年 BG. All rights reserved.
//

// 调试界面命令 注意:以下应答信号的 cmd = 发送信号的 cmd,length 可能不为 0,但符合格式要求。
/** 第一部分:*/

/** 启动电机,无应答信号返回。         (同上) */
#define CMD_START_MOTOR_DOWN            0x0b    
/** 电校正,收到应答表示电校正成功。    (同上) */
#define CMD_ELE_COMP_DOWN               0x0e
/** 磁校正,收到应答表示磁校正成功。    (同上) */
#define CMD_MEG_COMP_DOWN               0x0f
/** 角校正,收到应答表示角校正成功。    (同上) */
#define CMD_ANGLE_COMPESATION           0x10

/** 停电机,无应答信号返回。(发送此命令 length 建议设为 0, 有用数据仅为 cmd。) */
//⭐️⭐️⭐️以上四个命令必须要 CMD_STOP_MOTOR_DOWN 命令发送后方可发送,也就是说在发 次命令前,上述四个命令按钮应为灰色不可选中状态,避免误触。
#define CMD_STOP_MOTOR_DOWN             0x13

/** 
    读/写 Top 的 PID。当为读取包时,length 建议设为 0;收到应答包包 含读取回来的数据,格式为 parameters_packet_t 如下。
    当为写入包时,length=6;收到应答表 示写入完成。(其中 dataBuffer[6]包含 PID 数据)
*/
    typedef union{
         struct parameters_s{
             uint8_t cmd;
             uint8_t length;
             uint8_t frame;
             uint8_t dataBuffer[6];
             uint8_t crc8;
         }data;
         uint8_t buffer[sizeof(struct parameters_s)];
    }parameters_packet_t;
/**
    dataBuffer[0]~dataBuffer[1]:表示 Kp,小端格式,即 Kp = dataBuffer[1] * 256 + dataBuffer[0] dataBuffer[2]~dataBuffer[3]:表示 Ki
    dataBuffer[4]~dataBuffer[5]:表示 Kd 
*/

#define CMD_PID_TOP_PID                 0x20
/** 读/写 Medium 的 PID。(同上) */
#define CMD_PID_MEDIUM_PID              0x21
/** 读/写 Bottom 的 PID。(同上)收到此包的应答后读取或写入才是 真正的完成 */
#define CMD_PID_BOTTOM_PID              0x22

/** 读取,发送包 length 建议设为 0。收到应答包中包含读回来 的参数,应答包格式固定如下:(收到此包后继续发送 CMD_PID_TOP_PID,读取下一组 参数) */
    typedef union{
        struct data_packet_s {
            uint8_t cmd;
            uint8_t length; 
            uint8_t frame;
            uint8_t dataBuffer[4]; 
            uint8_t crc8;
        }packet;
        uint8_t buffer[sizeof(struct data_packet_s)];
    }wr_data_packet_t;
 
// 其中,dataBuffer[4]的数据是下面 parameters_t 的数据。

    typedef union{
         int32_t data;
         struct{
            int8_t  accTimeConstant:8;
            uint8_t followDeadBand:8;
            uint8_t followSpeed:8;
            uint8_t dirMotorRoll:1;
            uint8_t dirMotorPitch:1;
            uint8_t dirMotorYaw:1;
            uint8_t dirMegRoll:1;
            uint8_t dirMegPitch:1;
            uint8_t dirMegYaw:1;
            uint8_t testMode:1;
            uint8_t rcAngleMode:1;
         }parameters;
    }parameters_t;
/**
    accTimeConstant:   加速度比重
    followDeadBand:    死区
    followSpeed:       跟速
    dirMotorRoll:      Roll的电方向
    dirMotorPitch:     Pitch的电方向
    dirMotorYaw:       Yaw的电方向
    dirMegRoll:        Roll的磁方向
    dirMegPitch:       Pitch的磁方向
    dirMegYaw:         Yaw的磁方向
    testMode:          测试
    rcAngleMode:       角度
*/


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/** 第二部分 */
/**  */
#define CMD_READ_PARAMETERS             0x23
/** 写入,写入数据包的格式为 wr_data_packet_t,各项数据意 义如上。收到应答包表示此包写入完成,继续发送下一个写入包 CMD_PID_TOP_PID。 */
#define CMD_WRITE_PARAMETERS            0x24
/** 校正 M,收到应答表示 ADC 中位校正成功。(同上) */
#define CMD_ADC_MID_CAL_RX              0x55
/** 校正 A,无应答信号返回。(同上) */
#define CMD_ADC_CAL_RX                  0x56
/** 保存,收到应答表示 ADC 数据保存成功。(同上) */
#define CMD_ADC_CAL_SAVE_RX             0x57
/** 下发,测试控制板之间的通讯,无应答信号返回。(同上) */
#define CMD_TEST_ALL_NEXT               0x60
/** 下发上发,收到应答表示回路测试成功。(同上) */
#define CMD_TEST_ALL_DOWN_UP            0x64
/** 调试命令,无应答信号返回。(同上) */
#define CMD_BLE_DEBUG                   0xAA
/** 恢复,收到应答表示恢复默认值成功。(同上) */
#define CMD_SET_DEFAULT                 0x18

//设置界面里的命令
/** 自动校正。发送包建议 length 设为 0;收到应答包表示自动校正完成 */
#define CMD_AUTO_CALIBRATE              0x80
/**
    读配置参数。发送包 length 建议设为 0,应答包包 含读回的数据。格式如下: */
    typedef union{
        struct config_paramters_packet_s {
            uint8_t cmd;
            uint8_t length;
            uint8_t subCmd;
            uint8_t dataBuffer[16];
            uint8_t crc8;
        }packet;
        unsigned char buffer[sizeof(struct config_paramters_packet_s)];
    }config_paramters_packet_t;
/*
    subCmd:子命令,在读配置参数时,cmd = CMD_READ_CONFIG_PARAMETERS,subCmd = SUBCMD_READ_ALL。
    (在读配置参数时所有参数一起读回来,而不是一个个读取)应答包中 length >=5

    dataBuffer[0]:  跟随速度 followSpeed
    dataBuffer[1]:  RC PITCH 方向
    dataBuffer[2]:  RC YAW 方向
    dataBuffer[3]:  保留
    dataBuffer[4]:  软件版本
    dataBuffer[5]:  若 length>5,其他数据暂时保留,日后新增功能。
 */
#define CMD_READ_CONFIG_PARAMETERS      0x81
/**
    写入配置参数。配置参数一项一项写入,写入时 subCmd 表示写入的是哪个子命令。收到应答包表示相应的参数写入成功。
    length = 1;
    dataBuffer[0]:表示子命令下的数据。
 */
#define CMD_WRITE_CONFIG_PARAMETERS     0x82        
/** 子命令,跟随速度。 */
#define SUBCMD_FOLLOW_SPEED             0x10
/** 子命令,RC PITCH 的方向 */
#define SUBCMD_DIR_RC_PITCH             0x11
/** 子命令,RC YAW 的方向 */
#define SUBCMD_DIR_RC_YAW               0x12
/** 子命令,重心匹配,保留 */
#define SUBCMD_MATCH_GRAVITY            0x13
/** 子命令,软件版本,仅可读 */
#define SUBCMD_SOFTWARE_VERSION         0x14
/** 子命令,读取所有参数 */
#define SUBCMD_READ_ALL                 0x20


/** 其他命令 */
/**
    动态捕捉坐标。此命令由手机发送给控制板,手机只负责发送, 无应答信号返回。此命令格式如下: */
    typedef union{
        struct motion_capture_packet_s {
            uint8_t cmd;
            uint8_t length;
            uint8_t frame;
            uint8_t pos_x;
            uint8_t pos_y;
            uint8_t crc8;
        }packet;
        uint8_t buffer[sizeof(struct motion_capture_packet_s)];
    }motion_capture_packet_t;
/**
    pos_x:X 轴的相对坐标:选取框的中心点与屏幕中心的 X 轴相对值。 
    pos_y:Y 轴的相对坐标:选取框的中心点与屏幕中心的 Y 轴相对值。
 */

#define CMD_MOTION_CAPTURE              0x90
/** 需要显示的信息,模式、电压等。此命令由控制板发送 给手机,手机只负责接收。格式如下: */
     typedef union{
         struct information_display_packet_s {
            uint8_t cmd;
            uint8_t length;
            uint8_t mode;
            uint8_t voltage;
            uint8_t reserved[5];
            uint8_t crc8;
         }packet;
         uint8_t buffer[sizeof(struct information_display_packet_s)];
     }information_display_packet_t;
/**
    length = 6
    mode:模式
    voltage:电压 reserved[5]:保留值
 */
#define CMD_INFORMATION_DISPLAY         0x91
/** 切换摄像头。此命令只会收到。(此命令由控制板发送给手机, 手机只负责接收。) */
#define CMD_SWITCH_CAMERA               0x92
/** 拍照、录像或停止。此命令只会收到。(同上) */
#define CMD_PLAY_PAUSE                  0x93
/** 连拍。此命令只会收到。(同上) */
#define CMD_LONG_PRESS                  0x94

//蓝牙收发的 UUID
//蓝牙使用的 service
#define BLESERVICE_UUID                 @"22b3a000-2617-f8c9-d28a-6728eaeaeaae"
//蓝牙接收命令的 characteristics 的 UUID
#define BLESendCharacteristics_UUID     @"22b3a004-2617-f8c9-d28a-6728eaeaeaae"
//蓝牙发送命令的 characteristics 的 UUID
#define BLEReceiveCharacteristics_UUID  @"22b3a007-2617-f8c9-d28a-6728eaeaeaae"

//注:升级的协议格式里没有注明, 这里注明:蓝牙的接收与发送包的 characteristics 的 UUID 不一样,这两份协议的收发 characteristics 的 UUID 以这份为准。


#define WIDTH (8 * sizeof(u8)) 
#define TOPBIT (1 << (WIDTH - 1)) 
#define POLYNOMIAL 0x8D
#define u8 unsigned char

u8 crc_slow(u8 const *message, u8 nBytes);











